#include <QDebug>
#include <QRegExp>

#include "hybridpluginxmlhandler.h"

// NOTE: The XML handler has no error case handling whatsoever, so at this point
//       the XML files should be pretty much correct.

HybridPluginXmlHandler::HybridPluginXmlHandler(QFile *xmlFile)
    : QXmlStreamReader(xmlFile)
{
}

HybridPluginXmlHandler::~HybridPluginXmlHandler()
{
}

QSharedPointer<HybridPlugin> HybridPluginXmlHandler::parse()
{
    m_plugin = QSharedPointer<HybridPlugin> (new HybridPlugin);
    qDebug() << "Parsing start";

    readNextStartElement();
    while (!atEnd())
    {
        qDebug() << "HybridPluginXmlHandler::parse: Element" << name() << "read";
        if (name() == QLatin1String("plugin"))
            handlePluginTag();
        else
            readNextStartElement();
    }

    qDebug() << "Parsing end";
    return m_plugin;
}

void HybridPluginXmlHandler::handlePluginTag()
{
    while (readNextStartElement())
    {
        qDebug() << "HybridPluginXmlHandler::handlePluginTag: Element" << name() << "read";
        if (name() == QLatin1String("name"))
            m_plugin->setName(readElementText());
        else if (name() == QLatin1String("version"))
            m_plugin->setVersion(readElementText());
        else if (name() == QLatin1String("platforms"))
            handlePlatformsTag();
    }
}

void HybridPluginXmlHandler::handlePlatformsTag()
{
    while (readNextStartElement())
    {
        qDebug() << "HybridPluginXmlHandler::handlePlatformsTag: Element" << name() << "read";
        if (name() == QLatin1String("platform"))
            handlePlatformTag();
    }
}

void HybridPluginXmlHandler::handlePlatformTag()
{
    QSharedPointer<HybridPluginPlatform> platform = QSharedPointer<HybridPluginPlatform>(new HybridPluginPlatform(*m_plugin.data()));
    m_currentPlatform = platform;
    m_plugin->addPlatform(platform);

    while (readNextStartElement())
    {
        qDebug() << "HybridPluginXmlHandler::handlePlatformTag: Element" << name() << "read";
        if (name() == QLatin1String("name"))
        {
            m_currentPlatform->setName(readElementText());
        }
        else if (name() == QLatin1String("version"))
        {
            QString tag = readElementText();
            bool ok;
            int version = tag.toInt(&ok);
            if (ok)
            {
                m_currentPlatform->setVersion(version);
            }
        }
        else if (name() == QLatin1String("qt-version"))
        {
            QString tag = readElementText();
            QRegExp versionRx;
            versionRx.setPattern("^([0-9]).([0-9]).([0-9])$");
            if (versionRx.indexIn(tag) != -1)
            {
                bool ok;
                int qtVersion = QString(versionRx.cap(1) + versionRx.cap(2) + versionRx.cap(3)).toInt(&ok);
                if (ok)
                {
                    m_currentPlatform->setQtVersion(qtVersion);
                }
            }
        }
        else if (name() == QLatin1String("format"))
        {
            QString tag = readElementText();
            if (tag.toLower() == "lib")
                m_currentPlatform->setFormat(HybridPluginPlatform::Library);
            else if (tag.toLower() == "source")
                m_currentPlatform->setFormat(HybridPluginPlatform::Source);
        }
        else if (name() == QLatin1String("configuration"))
        {
            QString tag = readElementText();
            if (tag.toLower() == "debug")
                m_currentPlatform->setConfiguration(HybridPluginPlatform::Debug);
            else if (tag.toLower() == "release")
                m_currentPlatform->setConfiguration(HybridPluginPlatform::Release);
        }
        else if (name() == QLatin1String("url"))
        {
            m_currentPlatform->setUrl(readElementText());
        }
        else if (name() == QLatin1String("depends"))
        {
            handleDependsTag();
        }
    }
}

void HybridPluginXmlHandler::handleDependsTag()
{
    while (readNextStartElement())
    {
        qDebug() << "HybridPluginXmlHandler::handleDependsTag: Element" << name() << "read";
        if (name() == QLatin1String("item"))
            handleItemTag();
    }
}

void HybridPluginXmlHandler::handleItemTag()
{
    QString itemName, itemVersion;
    while (readNextStartElement())
    {
        qDebug() << "HybridPluginXmlHandler::handleItemTag: Element" << name() << "read";
        if (name() == QLatin1String("name"))
            itemName = readElementText();
        else if (name() == QLatin1String("version"))
            itemVersion = readElementText();
    }

    QSharedPointer<Dependency> dependency = QSharedPointer<Dependency>(new Dependency(itemName, itemVersion));
    m_currentPlatform->addDependency(dependency);
}
